package com.example.graphmovieapp.service.impl;

import com.example.graphmovieapp.domain.entity.Movie;
import com.example.graphmovieapp.domain.entity.Person;
import com.example.graphmovieapp.repository.MovieRepository;
import com.example.graphmovieapp.repository.PersonRepository;
import com.example.graphmovieapp.service.MovieService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;

/**
 * MovieService实现类，提供电影相关的业务操作
 * 
 * @author GraphMovieApp
 * @version 1.0
 */
@Service
@Transactional
public class MovieServiceImpl implements MovieService {

    private final MovieRepository movieRepository;
    private final PersonRepository personRepository;

    /**
     * 构造函数，注入Repository依赖
     * 
     * @param movieRepository 电影Repository
     * @param personRepository 人物Repository
     */
    @Autowired
    public MovieServiceImpl(MovieRepository movieRepository, PersonRepository personRepository) {
        this.movieRepository = movieRepository;
        this.personRepository = personRepository;
    }

    /**
     * 保存电影
     * 
     * @param movie 要保存的电影
     * @return 保存后的电影
     */
    @Override
    @Transactional
    public Movie saveMovie(Movie movie) {
        if (movie == null) {
            throw new IllegalArgumentException("电影不能为空");
        }
        return movieRepository.save(movie);
    }

    /**
     * 根据ID查找电影
     * 
     * @param id 电影ID
     * @return 匹配的电影，如果不存在则返回Optional.empty()
     */
    @Override
    @Transactional(readOnly = true)
    public Optional<Movie> findMovieById(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("电影ID不能为空");
        }
        return movieRepository.findById(id);
    }

    /**
     * 查找所有电影
     * 
     * @return 所有电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<Movie> findAllMovies() {
        return movieRepository.findAll();
    }

    /**
     * 根据ID删除电影
     * 
     * @param id 电影ID
     */
    @Override
    @Transactional
    public void deleteMovie(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("电影ID不能为空");
        }
        if (!movieRepository.existsById(id)) {
            throw new IllegalArgumentException("电影不存在，ID: " + id);
        }
        movieRepository.deleteById(id);
    }

    /**
     * 根据标题查找电影
     * 
     * @param title 电影标题
     * @return 匹配的电影，如果不存在则返回Optional.empty()
     */
    @Override
    @Transactional(readOnly = true)
    public Optional<Movie> findMovieByTitle(String title) {
        if (title == null || title.trim().isEmpty()) {
            throw new IllegalArgumentException("电影标题不能为空");
        }
        return movieRepository.findByTitle(title);
    }

    /**
     * 根据发行年份查找电影
     * 
     * @param released 发行年份
     * @return 匹配的电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<Movie> findMoviesByReleased(Integer released) {
        if (released == null) {
            throw new IllegalArgumentException("发行年份不能为空");
        }
        return movieRepository.findByReleased(released);
    }

    /**
     * 根据标题模糊查询电影
     * 
     * @param title 标题关键字
     * @return 包含关键字的电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<Movie> findMoviesByTitleContaining(String title) {
        if (title == null || title.trim().isEmpty()) {
            throw new IllegalArgumentException("标题关键字不能为空");
        }
        return movieRepository.findByTitleContaining(title);
    }

    /**
     * 根据标题模糊查询电影（支持分页）
     * 
     * @param title 标题关键字
     * @param pageable 分页参数
     * @return 分页的电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public Page<Movie> findMoviesByTitleContaining(String title, Pageable pageable) {
        if (title == null || title.trim().isEmpty()) {
            throw new IllegalArgumentException("标题关键字不能为空");
        }
        if (pageable == null) {
            throw new IllegalArgumentException("分页参数不能为空");
        }
        return movieRepository.findByTitleContaining(title, pageable);
    }

    /**
     * 根据发行年份范围查找电影
     * 
     * @param start 起始年份
     * @param end 结束年份
     * @return 在指定年份范围内的电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<Movie> findMoviesByReleasedBetween(Integer start, Integer end) {
        if (start == null || end == null) {
            throw new IllegalArgumentException("年份范围不能为空");
        }
        if (start > end) {
            throw new IllegalArgumentException("起始年份不能大于结束年份");
        }
        return movieRepository.findByReleasedBetween(start, end);
    }

    /**
     * 根据发行年份范围查找电影（支持分页）
     * 
     * @param start 起始年份
     * @param end 结束年份
     * @param pageable 分页参数
     * @return 分页的电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public Page<Movie> findMoviesByReleasedBetween(Integer start, Integer end, Pageable pageable) {
        if (start == null || end == null) {
            throw new IllegalArgumentException("年份范围不能为空");
        }
        if (start > end) {
            throw new IllegalArgumentException("起始年份不能大于结束年份");
        }
        if (pageable == null) {
            throw new IllegalArgumentException("分页参数不能为空");
        }
        return movieRepository.findByReleasedBetween(start, end, pageable);
    }

    /**
     * 查找指定演员参演的电影数量
     * 
     * @param name 演员姓名
     * @return 该演员参演的电影数量
     */
    @Override
    @Transactional(readOnly = true)
    public Long countMoviesActedByPerson(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("演员姓名不能为空");
        }
        return movieRepository.countMoviesActedByPerson(name);
    }

    /**
     * 查找指定导演执导的电影数量
     * 
     * @param name 导演姓名
     * @return 该导演执导的电影数量
     */
    @Override
    @Transactional(readOnly = true)
    public Long countMoviesDirectedByPerson(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("导演姓名不能为空");
        }
        return movieRepository.countMoviesDirectedByPerson(name);
    }

    /**
     * 查找同时担任演员和导演的电影
     * 
     * @param name 人物姓名
     * @return 该人物既参演又执导的电影列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<Movie> findMoviesActedAndDirectedByPerson(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("人物姓名不能为空");
        }
        return movieRepository.findMoviesActedAndDirectedByPerson(name);
    }

    /**
     * 查找合作演员（参演同一电影的不同演员）
     * 
     * @param name 演员姓名
     * @return 与该演员合作过的其他演员列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<Person> findCoActors(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("演员姓名不能为空");
        }
        return movieRepository.findCoActors(name);
    }

    /**
     * 创建电影并添加演员和导演
     * 
     * @param movie 电影对象
     * @param actorNames 演员姓名列表
     * @param directorNames 导演姓名列表
     * @return 创建的电影
     */
    @Override
    @Transactional
    public Movie createMovieWithActorsAndDirectors(Movie movie, List<String> actorNames, List<String> directorNames) {
        if (movie == null) {
            throw new IllegalArgumentException("电影不能为空");
        }
        if (movie.getTitle() == null || movie.getTitle().trim().isEmpty()) {
            throw new IllegalArgumentException("电影标题不能为空");
        }
        
        // 保存电影
        Movie savedMovie = movieRepository.save(movie);
        
        // 添加演员
        if (actorNames != null && !actorNames.isEmpty()) {
            for (String actorName : actorNames) {
                if (actorName != null && !actorName.trim().isEmpty()) {
                    Optional<Person> actorOpt = personRepository.findByName(actorName);
                    if (actorOpt.isPresent()) {
                        Person actor = actorOpt.get();
                        actor.addActedInMovie(savedMovie);
                        savedMovie.addActor(actor);
                        personRepository.save(actor);
                    } else {
                        // 如果演员不存在，可以创建一个新的演员记录
                        Person newActor = new Person(actorName, null);
                        newActor.addActedInMovie(savedMovie);
                        savedMovie.addActor(newActor);
                        personRepository.save(newActor);
                    }
                }
            }
        }
        
        // 添加导演
        if (directorNames != null && !directorNames.isEmpty()) {
            for (String directorName : directorNames) {
                if (directorName != null && !directorName.trim().isEmpty()) {
                    Optional<Person> directorOpt = personRepository.findByName(directorName);
                    if (directorOpt.isPresent()) {
                        Person director = directorOpt.get();
                        director.addDirectedMovie(savedMovie);
                        savedMovie.addDirector(director);
                        personRepository.save(director);
                    } else {
                        // 如果导演不存在，可以创建一个新的导演记录
                        Person newDirector = new Person(directorName, null);
                        newDirector.addDirectedMovie(savedMovie);
                        savedMovie.addDirector(newDirector);
                        personRepository.save(newDirector);
                    }
                }
            }
        }
        
        // 保存更新后的电影
        return movieRepository.save(savedMovie);
    }
}